package com.tuanzi.loan.schedule.receipt;

import com.base.common.log.LogService;
import com.tuanzi.loan.business.entity.product.product.LoanProductBusinessInfo;
import com.tuanzi.loan.business.entity.product.product.LoanProductInfo;
import com.tuanzi.loan.business.entity.product.product.LoanProductRechargeRecord;
import com.tuanzi.loan.business.repository.product.product.LoanProductBusinessInfoRepository;
import com.tuanzi.loan.business.repository.product.product.LoanProductInfoRepository;
import com.tuanzi.loan.business.repository.product.product.LoanProductRechargeRecordRepository;
import com.tuanzi.loan.business.service.product.product.LoanProductConsumeRecordService;
import com.tuanzi.loan.business.service.product.product.LoanProductInfoService;
import com.tuanzi.loan.business.service.product.product.impl.LoanProductInfoServiceImpl;
import com.tuanzi.loan.business.service.statistics.LoanProductClickUvService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.schedule.receipt.monitor.AbstractMonitor;
import com.tuanzi.loan.schedule.receipt.monitor.IMonitor;
import com.tuanzi.loan.schedule.receipt.monitor.sender.DingDingSender;
import com.tuanzi.loan.schedule.receipt.monitor.sender.DingTalkService;
import com.tuanzi.loan.schedule.receipt.monitor.template.TemplateFactory;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: hequnayu
 * @Date: 2019/6/5 17:26
 * @Description:
 */
@Debug
@Slf4j
@Service
public class StatisticsDailyClickUvRemaining {
    @Autowired
    private LoanProductInfoRepository loanProductInfoRepository;

    @Autowired
    private LoanProductInfoService loanProductInfoService;

    @Value("${prepay.off-line.dingding.url}")
    private String prepayUrl;

    @Value("${prepay.off-line.dingding.content}")
    private String prepayDingDingContent;

    @Autowired
    private DingTalkService dingTalkService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Scheduled(cron = "${cron.product-remaining-uv-task}")
    @Transactional(propagation= Propagation.NOT_SUPPORTED)
    public void statistic(){
        LogService.info("甲方标签库计算控量与自动上下线任务开始");
        Instant startTime = Instant.now();
        int count = 0;
        List<LoanProductInfo> productInfos = loanProductInfoRepository.listAllProductInfo();

        for (LoanProductInfo info : productInfos){
            Integer oldStatus = info.getStatus();
            if (info.getEveryDayOnlineTime() != null){
                int secondOfOnline = new DateTime(new Date()).getSecondOfDay();
                if (secondOfOnline >= info.getEveryDayOnlineTime()){ //到达上线时间
                    info.setStatus(1);
                }else{
                    info.setStatus(0);
                }
            }

            if (info.getEveryDayOfflineTime() != null){
                int secondOfOffline = new DateTime(new Date()).getSecondOfDay();
                if (secondOfOffline > info.getEveryDayOfflineTime()){ //到达下线时间
                    info.setStatus(0);
                }
            }

            if(info.getDayLimitClickUv() == null){
                info.setDayLimitClickUv(50000);
            }
            Integer dayLimitClickUv = info.getDayLimitClickUv(); //每天控量
            Integer oldDayRemainingClickUv = info.getDayRemainingClickUv() == null ? 0:info.getDayRemainingClickUv(); //原本每天剩余控量
            Integer clickUv = loanProductInfoService.getClickUv(info.getId(), LocalDate.now());
            Integer dayRemainingClickUv = dayLimitClickUv - clickUv; //新剩余控量
            info.setDayRemainingClickUv(dayRemainingClickUv);
            if (dayRemainingClickUv <= 0){
                info.setStatus(0); //已达总控量，下线产品
            }

            if (info.getStatus() != null && info.getStatus() == 1 && oldStatus != null && oldStatus == 1){
                if (info.getPrepayOffLine()){
                    String cacheHadOpenPrepay = LoanProductInfoServiceImpl.PRODUCT_HAD_OPEN_PERPAY_SWITCH_KEY + LocalDate.now().toString();
                    redisTemplate.opsForSet().add(cacheHadOpenPrepay,info.getId().toString());
                    redisTemplate.expire(cacheHadOpenPrepay, Duration.ofDays(1).getSeconds(), TimeUnit.SECONDS);
                    double balance = loanProductInfoService.getBalance(info.getId(),clickUv);
                    if(balance <= loanProductInfoService.getProductUvValue(info.getId())){
                        try {
                            dingTalkService.sendMessage(prepayUrl, String.format(prepayDingDingContent,info.getName(),info.getName()));
                        } catch (Exception e) {
                            LogService.error("预付下线发送钉钉消息失败", e);
                        }
                        info.setStatus(0);
                    }
                }
            }

            //当状态或者剩余控量发生变化时才更新
            if ((oldStatus != null && !oldStatus.equals(info.getStatus()))
                    || (!oldDayRemainingClickUv.equals(info.getDayRemainingClickUv()))){
                loanProductInfoRepository.updateLoanProductInfo(info);
                count++;
            }
        }
        Instant endTime = Instant.now();
        LogService.info("甲方标签库计算控量与自动上下线任务结束,耗时："+ ChronoUnit.SECONDS.between(startTime,endTime )+"秒；更新甲方数量："+count);
    }
}
